import {
  VuexModule,
  Module,
  Mutation,
  Action,
  getModule
} from 'vuex-module-decorators'
import { RouteConfig } from 'vue-router'
import { asyncRoutes, constantRoutes } from '@/router'
import store from '@/store'

const hasPermission = (roles: string[], route: RouteConfig) => {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

const deepCopy = (source: any): any => {
  if (!source) {
    return source
  }
  const sourceCopy: any = source instanceof Array ? [] : {}
  for (const item in source) {
    sourceCopy[item] =
      typeof source[item] === 'object' ? deepCopy(source[item]) : source[item]
  }
  return sourceCopy
}

export const filterAsyncRoutes = (routes: RouteConfig[], roles: string[]) => {
  const res: RouteConfig[] = []
  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })
  return res
}

export interface IPermissionState {
  routes: RouteConfig[];
  dynamicRoutes: RouteConfig[]
}

@Module({ dynamic: true, store, name: 'permission' })
class Permission extends VuexModule implements IPermissionState {
  public routes: RouteConfig[] = []
  public dynamicRoutes: RouteConfig[] = []

  @Mutation
  private SET_ROUTES (routes: RouteConfig[]) {
    this.routes = constantRoutes.concat(routes)
    this.dynamicRoutes = routes
  }

  /**
   *
   * @param roles 当前用户的角色
   * @returns filterAsyncRoutes 把动态路由与当前用户的角色进行匹配，过滤出用户可访问的路由表
   */
  @Action
  public GenerateRoutes (roles: string[]): Promise<RouteConfig[]> {
    // let accessedRoutes;
    // if (roles.includes("admin")) {
    //   accessedRoutes = asyncRoutes;
    // } else {
    //   accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
    // }
    // this.SET_ROUTES(accessedRoutes);

    return new Promise(resolve => {
      const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      this.SET_ROUTES(accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export const PermissionModule = getModule(Permission)
